package com.mgq.netty.c9;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.nio.charset.StandardCharsets;

/**
 * @author MaGuangQi
 * 第四种解决办法,使用LengthFieldBasedFrameDecoder处理,常用
 * LengthFieldBasedFrameDecoder:有几个常用属性
 * 1.int maxFrameLength,表示数据的最大长度（包括附加信息、长度标识等内容）,超过抛出TooLongFrameException
 * 2.int lengthFieldOffset,数据长度标识的起始偏移量
 * 3.int lengthFieldLength, 数据长度标识所占字节数（用于指明有用数据的长度
 * 4.int lengthAdjustment,长度表示与有用数据的偏移量
 * 5.int initialBytesToStrip 数据读取起点,不读取 0 ~ initialBytesToStrip 之间的数据
 * {@link LengthFieldBasedFrameDecoder}
 * @date 2021-12-06 15:36
 **/
public class FourthSolution {
    public static void main(String[] args) {
        //表示最大1024,用4个字节表示长度,长度的偏移量为0,读取0到所有

            //+--------+----------------+      +--------+----------------+
        //   | Length      | Actual Content |----->| Length    | Actual Content |
        //   | 0x0000000C | "HELLO, WORLD" |      | 0x0000000C | "HELLO, WORLD" |
        //   +--------+----------------+      +--------+----------------+
        //LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 0);

        //去掉长度
        //LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4);
        //
        //LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4);
        LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(1024, 2, 4, 1, 7);

        LoggingHandler loggingHandler = new LoggingHandler(LogLevel.DEBUG);
        EmbeddedChannel channel = new EmbeddedChannel(decoder,loggingHandler);
        ByteBuf byteBuf= ByteBufAllocator.DEFAULT.buffer();
        //send1(byteBuf, "HELLO, WORLD");
        send2(byteBuf, "HELLO, WORLD");
        channel.writeInbound(byteBuf);
    }

    private static void send1(ByteBuf byteBuf, String content) {
        // 对应这个LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 0);
        String s = content;
        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
        int length = bytes.length;
        byteBuf.writeInt(length);
        byteBuf.writeBytes(bytes);
    }
    private static void send2(ByteBuf byteBuf, String content) {
        //LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(1024, 2, 4, 1, 7);
        String s = content;
        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
        int length = bytes.length;
        //先写入2个字节的"CA",4个字节的长度,1个字节的版本,剩余的是内容

        byteBuf.writeBytes("CA".getBytes(StandardCharsets.UTF_8));
        //4个字节的长度
        byteBuf.writeInt(length);
        //定义一个版本0
        byteBuf.writeByte(0);
        byteBuf.writeBytes(bytes);
    }

}
